package com.Netty.heart.client;

import com.Netty.heart.comment.CustomHeartbeatHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * Created by thinkjoy on 2017/6/29.
 */
public class Client {
    private NioEventLoopGroup workGroup=new NioEventLoopGroup(4);
    private Channel channel;
    private Bootstrap bootstrap;

    public static void main(String[] args) throws  Exception{
        Client client=new Client();
        client.start();
        client.sendData();
    }

    public void sendData() throws Exception{
        Random random=new Random(System.currentTimeMillis());
        for (int i=0;i<10000;i++){
            if(channel!=null && channel.isActive()){
                String content="client msg "+i;
                ByteBuf buf=channel.alloc().buffer(5+content.getBytes().length);
                buf.writeInt(5+content.getBytes().length);
                buf.writeByte(CustomHeartbeatHandler.CUSTOM_MSG);
                buf.writeBytes(content.getBytes());
                channel.writeAndFlush(buf);
            }
            Thread.sleep(random.nextInt(20000));
        }
    }

    public void start(){
        try {
           bootstrap=new Bootstrap();
           bootstrap.group(workGroup)
                   .channel(NioSocketChannel.class)
                   .handler(new ChannelInitializer<SocketChannel>() {
                       @Override
                       protected void initChannel(SocketChannel socketChannel) throws Exception {
                           ChannelPipeline p=socketChannel.pipeline();
                           p.addLast(new IdleStateHandler(0,0,5));
                           p.addLast(new LengthFieldBasedFrameDecoder(1024,0,4,-4,0));
                           p.addLast(new ClientHnadler(Client.this));
                       }
                   });
           doConnect();
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 连接的方法
     */
    protected void doConnect() {
        if(channel !=null &&  channel.isActive()){
            return;
        }
        ChannelFuture future=bootstrap.connect("127.0.0.1",9527);
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                if(channelFuture.isSuccess()){
                    channel=channelFuture.channel();
                    System.out.println("成功连接到服务器");
                }else {
                    System.out.println("连接到服务器失败，10秒后尝试重连");
                    channelFuture.channel().eventLoop().schedule(new Runnable() {
                        @Override
                        public void run() {
                            doConnect();
                        }
                    },10, TimeUnit.SECONDS);
                }
            }
        });
    }
}
